package com.yeyks.cncallback.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.XML;
import com.google.common.collect.Maps;
import com.yeyks.cnbooking.Result.callback.CbDataSync;
import com.yeyks.cnbooking.Result.callback.CbHotelData;
import com.yeyks.cnbooking.Result.callback.CbOrderData;
import com.yeyks.cnbooking.Result.callback.CbRoomData;
import com.yeyks.cncallback.CNBookingCallBackService;
import com.yeyks.common.base.Arguments;
import com.yeyks.common.constants.OrderStatus;
import com.yeyks.common.constants.SyncTypeConst;
import com.yeyks.common.dto.mq.EsCbCallBackOrderMessage;
import com.yeyks.common.dto.mq.RefundMessage;
import com.yeyks.common.utils.apputil.redis.RedisService;
import com.yeyks.search.constants.EsIndexConstant;
import com.yeyks.search.pojo.model.EsHotelInfo;
import com.yeyks.search.pojo.param.EsHotelSearchParam;
import com.yeyks.search.pojo.result.hotel.EsHotelInfoVo;
import com.yeyks.search.service.ElasticSearchService;
import com.yeyks.search.service.MySearchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author: dagny
 * @date: 2019/10/9 0009 17:39
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CNBookingCallBackServiceImpl implements CNBookingCallBackService {

    private final ElasticSearchService elasticSearchService;

    private final RestHighLevelClient restHighLevelClient;

    private final MySearchService searchService;

    private final MqCnBookingProducerService mqProducerService;

    @Override
    public void cbReturnCallback(String xml) {
        JSONObject jsonObject = XML.toJSONObject(xml);
        jsonObject = (JSONObject) jsonObject.get("DataSync");
        CbDataSync cbDataSync = JSONUtil.toBean(jsonObject, CbDataSync.class);
        if (null != cbDataSync && Arguments.strNotNull(cbDataSync.getSyncType())) {
            int syncType = Integer.parseInt(cbDataSync.getSyncType());
            switch (syncType) {
                case SyncTypeConst.HOTEL:
                    //酒店更新
                    CbHotelData hotelData = cbDataSync.getData().getHotel();
                    this.editHotelStatusInES(hotelData);
                    break;
                case SyncTypeConst.HOTEL_ROOM:
                    //酒店，房间更新
                    CbRoomData roomData = cbDataSync.getData().getRoom();
                    this.editRoomStatusInES(roomData);
                    break;
                case SyncTypeConst.HOTEL_ROOM_RATE_PLAN:
                    //房态数据MQ存储(资源消耗过大)
                    /*String hotelId = EsIndexConstant.ID_PREX_CNBOOKING_HOTEL
                            + cbDataSync.getData().getHotel().getHotelId( );
                    List<EsHotelInfo> hotelInfoList = elasticSearchService.esHotelSearch( EsIndexConstant.INDEX_HOTEL2,
                            "cn", hotelId, 10, 1 );
                    if ( !CollectionUtils.isEmpty(hotelInfoList)) {
                        //如果没有那个酒店，就不进行发送信息（关闭）
                        mqProducerService.sendSaveReturnCallBack(xml);
                    }*/
                    break;
                case SyncTypeConst.CN_ORDER:
                    //订单状态更改
                    CbOrderData orderData = cbDataSync.getData().getOrder();
                    log.info("订单Id为{}，状态转换为{}，备注为{}", orderData.getOrderId(), orderData.getOrderStatusId(),
                            orderData.getRemark());
                    this.editOrderStatusInES(orderData);
                    break;
                default:
                    //其他操作
                    break;
            }
        }
    }

    /**
     * 更新ES中CnBooking的【酒店】数据
     *
     * @param hotelData 酒店数据
     */
    private void editHotelStatusInES(CbHotelData hotelData) {

        String id = EsIndexConstant.ID_PREX_CNBOOKING_HOTEL + hotelData.getHotelId();

        EsHotelSearchParam param = new EsHotelSearchParam();
        param.setHotelId(id);
        List<EsHotelInfoVo> esHotelInfoVoList = searchService.searchHotel(param);
        if (!CollectionUtils.isEmpty(esHotelInfoVoList)) {
            UpdateRequest updateRequest = new UpdateRequest(EsIndexConstant.INDEX_HOTEL2, EsIndexConstant.NORMAL_TYPE,
                    id);
            try {
                Map<String, Object> map = Maps.newHashMap();
                // 015004 上线 ,  015005 下线
                if ("015004".equals(hotelData.getHotelStatus())) {
                    map.put("valid", true);
                } else {
                    map.put("valid", false);
                }
                updateRequest.doc(map).routing(EsIndexConstant.ROUTING_HOTEL);
                restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.info("！！！更新CnBooking的【酒店】数据异常！！！");
            }
        }
    }


    /**
     * 更新ES中CnBooking的【房间】数据
     *
     * @param roomData 房间数据
     */
    private void editRoomStatusInES(CbRoomData roomData) {

        String id = EsIndexConstant.ID_PREX_CNBOOKING_ROOM + roomData.getRoomId();

        UpdateRequest updateRequest = new UpdateRequest(EsIndexConstant.INDEX_HOTEL2, EsIndexConstant.NORMAL_TYPE,
                id);

        try {
            Map<String, Object> map = Maps.newHashMap();
            // 015004 上线 ,  015005 下线
            if ("015004".equals(roomData.getRoomStatus())) {
                map.put("valid", true);
            } else {
                map.put("valid", false);
            }
            updateRequest.doc(map).routing(EsIndexConstant.ROUTING_HOTEL);
            restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.info("！！！更新CnBooking的【房间】数据异常！！！");
        }
    }

    /**
     * 更新ES中CnBooking的【订单】数据
     * 数据库状态，1待支付，2待入住，3已完成，4支付失败，5待退款，6已退款，7入住中，8已取消，9已评论，0已删除
     *
     * @param orderData 订单数据
     */
    private void editOrderStatusInES(CbOrderData orderData) {

        int orderStatus = Integer.parseInt(orderData.getOrderStatusId());

        log.info("CbOrderData = {}", orderData);

        if (orderStatus > 9) {
            //发送订单消息--> 到延迟队列中(塞入状态需要根据查询时间修改， 这里的status暂时不影响修改)
            mqProducerService.sendCNBookingOrderUpdate(new EsCbCallBackOrderMessage()
                    .setSourceOrderId(orderData.getOrderId())
                    .setStatus(OrderStatus.preCheckIn)
                    .setRemark(orderData.getRemark())
            );

        } else if (orderStatus == 8) {
            log.info("status = {}", orderData.getOrderStatusId());
            //已取消（取消订单及时修改，不存入延迟队列中）
            //在MQ中进行退款操作(传入orderID)
            mqProducerService.sendCNBookingCancelOrder(new RefundMessage()
                    .setSourceOrderId(orderData.getOrderId()));

        }

    }
}
